package com.hskn.hss.module.grid.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.domain.BaseEntity;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.core.utils.uuid.IdUtils;
import com.hskn.hss.entity.LatLngEntity;
import com.hskn.hss.entity.TreeEntity;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.carPlan.entity.CarPlan;
import com.hskn.hss.module.carPlan.mapper.CarPlanMapper;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.empPlan.entity.EmpPlan;
import com.hskn.hss.module.empPlan.mapper.EmpPlanMapper;
import com.hskn.hss.module.empWorkPoints.entity.EmpWorkPoints;
import com.hskn.hss.module.empWorkPoints.service.IEmpWorkPointsService;
import com.hskn.hss.module.grid.To.GridTo;
import com.hskn.hss.module.grid.entity.Grid;
import com.hskn.hss.module.grid.entity.GridCheckwork;
import com.hskn.hss.module.grid.mapper.CheckWorkMapper;
import com.hskn.hss.module.grid.mapper.GridMapper;
import com.hskn.hss.module.grid.service.IGridService;
import com.hskn.hss.module.grid.vo.*;
import com.hskn.hss.module.gridbind.entity.GridBind;
import com.hskn.hss.module.gridbind.mapper.GridBindMapper;
import com.hskn.hss.module.sysDictType.entity.SysDictType;
import com.hskn.hss.module.sysDictType.service.SysDictTypeService;
import com.hskn.hss.module.tlcar.entity.TlCar;
import com.hskn.hss.module.tlcar.service.ITlCarService;
import com.hskn.hss.module.tlemployee.entity.TlEmployee;
import com.hskn.hss.module.tlemployee.service.ITlEmployeeService;
import com.hskn.hss.utils.*;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-08
 */
@Service
public class GridServiceImpl extends ServiceImpl<GridMapper, Grid> implements IGridService {
    @Resource
    GridMapper gridMapper;
    @Resource
    GridBindMapper gridBindMapper;
    @Resource
    SysDepartMapper sysDepartMapper;
    @Autowired
    private ISysDepartService departService;
    @Resource
    private EmpPlanMapper empPlanMapper;
    @Resource
    private CarPlanMapper carPlanMapper;
    @Resource
    private CheckWorkMapper checkWorkMapper;
    //    @Resource
    //    WorkPlanMapper workPlanMapper;
//    @Resource
//    JxqsPlanMapper jxqsPlanMapper;
//    @Resource
//    LjqyWorkPlanMapper ljqyWorkPlanMapper;
//    @Resource
//    LjzyWorkPlanMapper ljzyWorkPlanMapper;
    @Resource
    private SysDictTypeService sysDictTypeService;
    @Autowired
    private LocationUtils locationUtils;

    @Autowired
    private ITlCarService tlCarService;

    @Autowired
    private ITlEmployeeService tlEmployeeService;
    @Autowired
    private IEmpWorkPointsService empWorkPointsService;

    private Double placeDistance = 20.0;

    /**
     * 判断给定时间段[startX,endX]是否与已知时间段存在交集,不存在返回true
     *
     * @param startX     例：2020/02/18 00:00:00
     * @param endX       例：2020/04/18 24:00:00
     * @param originList 正序存储的时间段集合[{start:A0,end:A1},{start:B0,end:B1}]
     * @return
     */
    public static boolean isNormal(String startX, String endX, List<Map<String, Object>> originList) {
        if (!isEmpty(startX) && !isEmpty(endX)) {
            startX = formatDate(startX);
            endX = formatDate(endX);
            if (originList != null && originList.size() > 0) {
                List<String> startList = new ArrayList<String>();
                List<String> endList = new ArrayList<String>();
                for (int i = 0; i < originList.size(); i++) {
                    startList.add(formatDate((String) originList.get(i).get("start")));
                    endList.add(formatDate((String) originList.get(i).get("end")));
                }
                String minStart = startList.get(0);
                String maxEnd = endList.get(endList.size() - 1);
                if (endX.compareTo(minStart) < 0) {
                    return true;
                }
                if (startX.compareTo(maxEnd) > 0) {
                    return true;
                }
                int minStartIndex = 0;
                if (startX.compareTo(minStart) > 0) {
                    if (startX.compareTo(endList.get(minStartIndex)) > 0) {// 即startX>A1
                        for (int i = minStartIndex; i < startList.size(); i++) {
                            if (startX.compareTo(startList.get(i)) < 0) {
                                if (endX.compareTo(startList.get(i)) < 0) {
                                    return true;
                                }
                            } else {
                                minStartIndex += 1;
                                continue;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    public static boolean isEmpty(String object) {
        if (object == null) {
            object = "";
        }
        return object.length() == 0;
    }

    public static String formatDate(String date) {
        if (date != null) {
            date = date.replace("/", "").replace(":", "").replace(" ", "");
        } else {
            date = "";
        }
        return date;
    }

    @Override
    @DataScope(deptAlias = "depid", userAlias = "manager_id, bind_person_ids, create_uid, update_uid")
    public JSONObject mList(BaseEntity entity, JSONObject params) throws HssException {
        JSONObject json = new JSONObject();
        List<String> depIds = null;
        QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().orderByDesc(Grid::getCreateTime);
        String depid = params.getString("depid");
        if (depid != null && depid != "") {
            depIds = departService.getChildIdsByIId(depid);
        }
        if (StringUtils.isNotEmpty(depid)) {
            queryWrapper.lambda().in(Grid::getDepid, depIds);
        }
        String type = params.getString("type");
        if (StringUtils.isNotEmpty(type)) {
            queryWrapper.lambda().eq(Grid::getType, type);
        }
        String name = params.getString("name");
        if (StringUtils.isNotEmpty(name)) {
            queryWrapper.lambda().like(Grid::getName, name);
        }
        String isGuideboard = params.getString("isGuideboard");
        if (StringUtils.isNotEmpty(isGuideboard)) {
            queryWrapper.lambda().like(Grid::getIsGuideboard, isGuideboard);
        }
        queryWrapper.lambda().eq(Grid::getGridType, 0);
        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
        Page<Grid> gridPage = new Page<>(page, size, true);
        if (entity.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(entity.getParams().get("dataScope"))) {
            queryWrapper.lambda().apply(entity.getParams().get("dataScope").toString());
        }
        IPage<Grid> iPage = gridMapper.selectPage(gridPage, queryWrapper);
        json.put("total", iPage.getTotal());
        json.put("size", iPage.getSize());
        json.put("pages", iPage.getPages());
        json.put("current", iPage.getCurrent());
        json.put("grids", iPage.getRecords());
        return json;
    }

    @Override
    @DataScope(deptAlias = "depid", userAlias = "manager_id, bind_person_ids, create_uid, update_uid")
    public GridVO getList(BaseEntity entity, GridTo gridTo) throws HssException {
        GridVO gridVO = new GridVO();
        QueryWrapper<GridBind> gridBindQueryWrapper = new QueryWrapper<>();
        if (null != gridTo.getGridIdList() && !gridTo.getGridIdList().isEmpty()) {
            gridBindQueryWrapper.lambda().in(GridBind::getItemId, gridTo.getItemIdList());
        }
        List<GridBind> gridBindList = gridBindMapper.selectList(gridBindQueryWrapper);
        Map<String, List<GridBind>> gridBindMap = gridBindList.stream().collect(Collectors.groupingBy(GridBind::getGridId));
        QueryWrapper<Grid> gridQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(gridTo.getName())) {
            gridQueryWrapper.lambda().like(Grid::getName, gridTo.getName());
        }
        if (StringUtils.isNotEmpty(gridTo.getDepid())) {
            List<String> depids = departService.getChildIdsByIId(gridTo.getDepid());
            gridQueryWrapper.lambda().in(Grid::getDepid, depids);
        }
        gridQueryWrapper.lambda().eq(Grid::getGridType, "1");
        if (entity.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(entity.getParams().get("dataScope"))) {
            gridQueryWrapper.lambda().apply(entity.getParams().get("dataScope").toString());
        }
        List<Grid> gridList = gridMapper.selectList(gridQueryWrapper);
        for (Grid grid : gridList) {
            List itemlist = new ArrayList();
            List<GridBind> gridBindList1 = gridBindMap.get(grid.getGridId());
            GridMXVO gridMXVO = new GridMXVO();
            gridMXVO.setId(grid.getGridId());
            gridMXVO.setName(grid.getName());
            gridMXVO.setDepName(grid.getDepName());
            gridMXVO.setArea(grid.getArea());
            gridMXVO.setDeptId(grid.getDepid());
            gridMXVO.setIsEnable(grid.getIsEnable());
            if (StringUtils.isNotEmpty(gridBindList1)) {
                for (GridBind gridBind : gridBindList1) {
                    itemlist.add(gridBind.getItemId());
                }
                gridMXVO.setItemIdList(itemlist);
            }
            gridVO.getGridMXVOList().add(gridMXVO);
        }
        gridVO.setGridMXVOList(gridVO.getGridMXVOList());
        return page(gridTo, gridVO.getGridMXVOList());
    }

    private GridVO page(GridTo gridTo, List<GridMXVO> list) {
        // 分页
        Long page = StringUtils.isEmpty(gridTo.getPage()) ? 1 : gridTo.getPage();
        Long size = StringUtils.isEmpty(gridTo.getSize()) ? 10 : gridTo.getSize();
        GridVO gridVO = new GridVO();
        gridVO.setTotal((long) list.size());
        gridVO.setCurrent(page);
        gridVO.setSize(size);
        BigDecimal pageSizeB = new BigDecimal(size);
        BigDecimal sizeB = new BigDecimal(list.size());
        gridVO.setPage(Long.valueOf(sizeB.divide(pageSizeB, BigDecimal.ROUND_CEILING).toString()));
        gridVO.setGridMXVOList(new ArrayList<>());
        for (int i = 0; i < list.size(); i++) {
            if (i >= size * (page - 1) && i < size * page) {
                gridVO.getGridMXVOList().add(list.get(i));
            }
        }
        return gridVO;
    }

    @Override
    public List<TreeEntity> tree(GridTo gridTo) {
        List<TreeEntity> treeList = sysDepartMapper.getTreeList();
        List<TreeEntity> grids = gridMapper.getGridTree(gridTo.getType(), gridTo.getGridType(), gridTo.getIsEnable());
        treeList.addAll(grids);
        List<TreeEntity> trees = TreeUtil.RecursiveAddress(treeList);
        return trees;
    }

    @Override
    public void mUpdate(JSONObject params) throws HssException {
        if (StringUtils.isEmpty(params) || StringUtils.isEmpty(params.getString("gridId"))) {
            throw new HssException("参数错误");
        }
        Grid grid = JSON.parseObject(params.toJSONString(), Grid.class);
        gridMapper.updateById(grid);
    }

    @Override
    public void add(JSONObject params) throws HssException {
        String uid = LoginUtils.getUser().getUid();
        Grid grid = JSON.parseObject(params.toJSONString(), Grid.class);
        if (StringUtils.isEmpty(grid) || StringUtils.isEmpty(grid.getName())
                || StringUtils.isEmpty(grid.getType()) || StringUtils.isEmpty(grid.getDepid())) {
            throw new HssException("参数错误");
        }
        grid.setCreateUid(uid);
        gridMapper.insert(grid);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public GridMessageVo delete(JSONObject params) throws HssException {
        if (StringUtils.isEmpty(params) || StringUtils.isEmpty(params.getString("gridIds"))) {
            throw new HssException("参数错误");
        }
        String message = "";
        String idStr = params.getString("gridIds");
        String[] ids = idStr.split(",");
        List<String> idsList = Arrays.asList(ids);
        QueryWrapper<EmpPlan> empPlanQueryWrapper = new QueryWrapper<>();
        empPlanQueryWrapper.lambda().in(EmpPlan::getGridId, idsList);
        List<EmpPlan> empPlanList = empPlanMapper.selectList(empPlanQueryWrapper);

        QueryWrapper<CarPlan> carPlanQueryWrapper = new QueryWrapper<>();
        carPlanQueryWrapper.lambda().in(CarPlan::getGridId, idsList);
        List<CarPlan> carPlanList = carPlanMapper.selectList(carPlanQueryWrapper);

        if (empPlanList.isEmpty() && carPlanList.isEmpty()) {
            gridMapper.deleteBatchIds(idsList);
            QueryWrapper<GridCheckwork> gridCheckworkQueryWrapper = new QueryWrapper<>();
            gridCheckworkQueryWrapper.lambda().in(GridCheckwork::getGridId, idsList);
            checkWorkMapper.delete(gridCheckworkQueryWrapper);
        } else {
            message = "此网格绑定人员排班或者车辆作业排班";
        }
        GridMessageVo gridMessageVo = new GridMessageVo();
        gridMessageVo.setMessage(message);
        return gridMessageVo;
    }

    @Override
    public Grid detail(JSONObject params) throws HssException {
        if (StringUtils.isEmpty(params)) {
            throw new HssException("参数错误");
        }

        Grid grid;
        if (StringUtils.isNotEmpty(params.getString("gridId"))) {
            grid = gridMapper.selectById(params.getString("gridId"));
        } else if (StringUtils.isNotEmpty(params.getString("gridType"))) {
            QueryWrapper<Grid> gridQueryWrapper = new QueryWrapper<>();
            gridQueryWrapper.lambda().eq(Grid::getGridType, params.getString("gridType"));
            gridQueryWrapper.lambda().last(" limit 1");
            grid = gridMapper.selectOne(gridQueryWrapper);
        } else {
            throw new HssException("参数错误");
        }

        if (Objects.isNull(grid)){
            throw new HssException("未查到网格信息");
        }

        if (grid.getGridType() == 1) {
            QueryWrapper<GridCheckwork> gridCheckworkQueryWrapper = new QueryWrapper<>();
            gridCheckworkQueryWrapper.lambda().eq(GridCheckwork::getGridId, grid.getGridId());
            //获取grid数据
            List<GridCheckwork> gridCheckworkList = checkWorkMapper.selectList(gridCheckworkQueryWrapper);
            List<GridCheckworkVo> gridCheckworkVoList = new ArrayList<>();
            List<GridCheckwork> gridCheckworkListOut = new ArrayList<>();

            if (CollectionUtils.isNotEmpty(gridCheckworkList)) {
                Map<String, List<GridCheckwork>> gridCheckworkMap = gridCheckworkList.stream().collect(Collectors.groupingBy(GridCheckwork::getCheckWorkName));
                for (List<GridCheckwork> gridCheckworkList1 : gridCheckworkMap.values()) {
                    //冬夏季排班
                    GridCheckwork gridCheckwork = new GridCheckwork();
                    GridCheckworkVo gridCheckworkVo = new GridCheckworkVo();
                    if (gridCheckworkList1.size() > 1) {
                        //第一条合并
                        BeanUtils.copyProperties(gridCheckworkList1.get(0), gridCheckwork);
                        for (GridCheckwork checkwork : gridCheckworkList1) {
                            if (checkwork.getType() == 1) {
                                //夏季班合并
                                gridCheckwork.setSumStartTime(checkwork.getStartTime());
                                gridCheckwork.setSumEndTime(checkwork.getEndTime());
                                gridCheckwork.setReqType("1");
                            } else if (checkwork.getType() == 2) {
                                //冬季班合并
                                gridCheckwork.setWinStartTime(checkwork.getStartTime());
                                gridCheckwork.setWinEndTime(checkwork.getEndTime());
                            }
                        }
                        gridCheckwork.setStartTime("");
                        gridCheckwork.setEndTime("");
                        //固定班
                    } else {
                        BeanUtils.copyProperties(gridCheckworkList1.get(0), gridCheckwork);
                        gridCheckwork.setReqType("0");
                    }

                    BeanUtils.copyProperties(gridCheckwork, gridCheckworkVo);
                    gridCheckworkVoList.add(gridCheckworkVo);
//                    gridCheckworkListOut.add(gridCheckwork);

                }
            }
            grid.setGridCheckworkVoList(gridCheckworkVoList);
//            grid.setGridCheckworkList(gridCheckworkListOut);
//            gridCheckworkQueryWrapper.lambda().eq(GridCheckwork::getGridId, grid.getGridId());
//            grid.setGridCheckworkList(checkWorkMapper.selectList(gridCheckworkQueryWrapper));
        }
        return grid;
    }

    @Override
    public Map<String, Grid> getGridMap(QueryWrapper<Grid> gridQueryWrapper) {
        List<Grid> gridList = gridMapper.selectList(gridQueryWrapper);
        Map<String, Grid> gridMap = new HashMap<>();
        if (!gridList.isEmpty()) {
            gridMap = GroupingByUtils.getGroupingForMapEntity(gridList, Grid::getGridId, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        return gridMap;
    }

    @Override
    public Grid create(GridTo gridTo) throws HssException, ParseException {
        String uid = LoginUtils.getUser().getUid();
        QueryWrapper<Grid> gridQueryWrapper = new QueryWrapper<>();
        gridQueryWrapper.lambda().eq(Grid::getGridType, gridTo.getGridType());
        gridQueryWrapper.lambda().eq(Grid::getName, gridTo.getName());
        List<Grid> gridList = gridMapper.selectList(gridQueryWrapper);
        Grid grid = new Grid();

        if (gridList.isEmpty()) {
            //考勤段信息判断
            List<GridCheckwork> gridCheckworkList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(gridTo.getGridCheckworkList()) && gridTo.getGridCheckworkList().size() > 0) {
                //考勤段名称查重
                for (GridCheckwork gridCheckwork : gridTo.getGridCheckworkList()) {
                    GridCheckwork gridCheckwork1 = new GridCheckwork();
                    if (gridCheckwork.getReqType().equals("0")) {
                        //固定班
                        BeanUtils.copyProperties(gridCheckwork, gridCheckwork1);
                        gridCheckwork1.setType(0);
                        gridCheckworkList.add(gridCheckwork1);
                    } else if (gridCheckwork.getReqType().equals("1")) {
                        //夏季班
                        BeanUtils.copyProperties(gridCheckwork, gridCheckwork1);
                        gridCheckwork1.setStartTime(gridCheckwork.getSumStartTime());
                        gridCheckwork1.setEndTime(gridCheckwork.getSumEndTime());
                        gridCheckwork1.setType(1);
                        gridCheckworkList.add(gridCheckwork1);
                        //冬季班
                        GridCheckwork gridCheckwork2 = new GridCheckwork();
                        BeanUtils.copyProperties(gridCheckwork, gridCheckwork2);
                        gridCheckwork2.setStartTime(gridCheckwork.getWinStartTime());
                        gridCheckwork2.setEndTime(gridCheckwork.getWinEndTime());
                        gridCheckwork2.setType(2);
                        gridCheckworkList.add(gridCheckwork2);
                    }

                }

                Map<Integer, List<GridCheckwork>> CheckWorkType = gridCheckworkList.stream().collect(Collectors.groupingBy(GridCheckwork::getType));
                for (List<GridCheckwork> gridCheckwork : CheckWorkType.values()) {
                    List<String> CheckWorkName = gridCheckwork.stream().map(GridCheckwork::getCheckWorkName).collect(Collectors.toList());
                    if (!AttributeUtils.RepeatedCheck(CheckWorkName)) {
                        throw new HssException("考勤段名称重复");
                    }
                }
                //考勤段时间段查重
                for (List<GridCheckwork> gridCheckwork : CheckWorkType.values()) {
                    List<String> times = new ArrayList<>();
                    for (GridCheckwork gridCheckwork1 : gridCheckwork) {
                        String ab = gridCheckwork1.getStartTime() + "-" + gridCheckwork1.getEndTime();
                        times.add(ab);
                    }
                    if (!AttributeUtils.IntervalComparisonAll(times)) {
                        throw new HssException("考勤段时间段重复");
                    }
                }
            }

            BeanUtils.copyProperties(gridTo, grid);
            if (null != gridTo.getLatLngEntityList() && !gridTo.getLatLngEntityList().isEmpty()) {
                JSONArray jsonArray = new JSONArray();
                for (LatLngEntity latLngEntity : gridTo.getLatLngEntityList()) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("lat", latLngEntity.getLat());
                    jsonObject.put("lng", latLngEntity.getLng());
                    jsonArray.add(jsonObject);
                }
                grid.setLnglat(jsonArray.toString());
            }
            if (null != gridTo.getRectangularEntity()) {
                JSONObject jsonArray = new JSONObject();

                JSONObject kqJsonObject = new JSONObject();

                kqJsonObject.put("lat", gridTo.getRectangularEntity().getKq().getLat());
                kqJsonObject.put("lng", gridTo.getRectangularEntity().getKq().getLng());
                jsonArray.put("kq", kqJsonObject);

                JSONObject lqJsonObject = new JSONObject();
                lqJsonObject.put("lat", gridTo.getRectangularEntity().getLq().getLat());
                lqJsonObject.put("lng", gridTo.getRectangularEntity().getLq().getLng());
                jsonArray.put("Lq", lqJsonObject);

                grid.setLnglat(jsonArray.toString());
            }
            grid.setCreateTime(new Date());
            gridMapper.insert(grid);

            if (CollectionUtils.isNotEmpty(gridTo.getGridCheckworkList()) && gridTo.getGridCheckworkList().size() > 0) {
                for (GridCheckwork gridCheckwork : gridCheckworkList) {
                    gridCheckwork.setGridId(grid.getGridId());
                    gridCheckwork.setCreatUid(uid);
                    gridCheckwork.setCreatTime(new Date());
                    checkWorkMapper.insert(gridCheckwork);
                }
                grid.setGridCheckworkList(gridCheckworkList);
            }
        }

        return grid;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Grid update(GridTo gridTo) throws HssException, ParseException {
        String uid = LoginUtils.getUser().getUid();
        Grid grid = gridMapper.selectById(gridTo.getGridId());

        QueryWrapper<Grid> gridQueryWrapper = new QueryWrapper<>();
        gridQueryWrapper.lambda().eq(Grid::getGridType, gridTo.getGridType());
        gridQueryWrapper.lambda().eq(Grid::getGridId, gridTo.getGridId());
        List<Grid> gridList = gridMapper.selectList(gridQueryWrapper);


        if (!gridList.isEmpty()) {
            for (Grid grid1 : gridList) {
                if (!grid1.getName().equals(gridTo.getName())) {
                    if (StringUtils.isNotEmpty(gridTo.getName()) && StringUtils.isNotEmpty(grid1.getName()) && !grid1.getName().equals(gridTo.getName())) {
                        throw new HssException("名称重复");
                    }
                }
            }
            BeanUtils.copyProperties(gridTo, grid);

            //考勤段信息判断
            List<GridCheckwork> gridCheckworkList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(gridTo.getGridCheckworkList()) && gridTo.getGridCheckworkList().size() > 0) {
                //考勤段名称查重
                for (GridCheckwork gridCheckwork : gridTo.getGridCheckworkList()) {
                    GridCheckwork gridCheckwork1 = new GridCheckwork();
                    if (gridCheckwork.getReqType().equals("0")) {
                        //固定班
                        BeanUtils.copyProperties(gridCheckwork, gridCheckwork1);
                        gridCheckwork1.setType(0);
                        gridCheckworkList.add(gridCheckwork1);
                    } else if (gridCheckwork.getReqType().equals("1")) {
                        //夏季班
                        BeanUtils.copyProperties(gridCheckwork, gridCheckwork1);
                        gridCheckwork1.setStartTime(gridCheckwork.getSumStartTime());
                        gridCheckwork1.setEndTime(gridCheckwork.getSumEndTime());
                        gridCheckwork1.setType(1);
                        gridCheckworkList.add(gridCheckwork1);
                        //冬季班
                        GridCheckwork gridCheckwork2 = new GridCheckwork();
                        BeanUtils.copyProperties(gridCheckwork, gridCheckwork2);
                        gridCheckwork2.setStartTime(gridCheckwork.getWinStartTime());
                        gridCheckwork2.setEndTime(gridCheckwork.getWinEndTime());
                        gridCheckwork2.setType(2);
                        gridCheckworkList.add(gridCheckwork2);
                    }

                }

                Map<Integer, List<GridCheckwork>> CheckWorkType = gridCheckworkList.stream().collect(Collectors.groupingBy(GridCheckwork::getType));
                for (List<GridCheckwork> gridCheckwork : CheckWorkType.values()) {
                    List<String> CheckWorkName = gridCheckwork.stream().map(GridCheckwork::getCheckWorkName).collect(Collectors.toList());
                    if (!AttributeUtils.RepeatedCheck(CheckWorkName)) {
                        throw new HssException("考勤段名称重复");
                    }
                }
                //考勤段时间段查重
                for (List<GridCheckwork> gridCheckwork : CheckWorkType.values()) {
                    List<String> times = new ArrayList<>();
                    for (GridCheckwork gridCheckwork1 : gridCheckwork) {
                        String ab = gridCheckwork1.getStartTime() + "-" + gridCheckwork1.getEndTime();
                        times.add(ab);
                    }
                    if (!AttributeUtils.IntervalComparisonAll(times)) {
                        throw new HssException("考勤段时间段重复");
                    }
                }
            }
            if (null != gridTo.getLatLngEntityList() && !gridTo.getLatLngEntityList().isEmpty()) {
                JSONArray jsonArray = new JSONArray();
                for (LatLngEntity latLngEntity : gridTo.getLatLngEntityList()) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("lat", latLngEntity.getLat());
                    jsonObject.put("lng", latLngEntity.getLng());
                    jsonArray.add(jsonObject);
                }
                grid.setLnglat(jsonArray.toString());
            }
            if (null != gridTo.getRectangularEntity()) {
                JSONObject jsonArray = new JSONObject();

                JSONObject kqJsonObject = new JSONObject();

                kqJsonObject.put("lat", gridTo.getRectangularEntity().getKq().getLat());
                kqJsonObject.put("lng", gridTo.getRectangularEntity().getKq().getLng());
                jsonArray.put("kq", kqJsonObject);

                JSONObject lqJsonObject = new JSONObject();
                lqJsonObject.put("lat", gridTo.getRectangularEntity().getLq().getLat());
                lqJsonObject.put("lng", gridTo.getRectangularEntity().getLq().getLng());
                jsonArray.put("Lq", lqJsonObject);

                grid.setLnglat(jsonArray.toString());
            }
            grid.setUpdateTime(new Date());
            gridMapper.updateById(grid);

            if (grid.getGridType() == 1) {
                if (StringUtils.isNotEmpty(grid.getGridType()) && grid.getGridType() == 1) {
                    QueryWrapper<GridCheckwork> gridCheckworkQueryWrapper = new QueryWrapper<>();
                    gridCheckworkQueryWrapper.lambda().eq(GridCheckwork::getGridId, grid.getGridId());
                    checkWorkMapper.delete(gridCheckworkQueryWrapper);

                    for (GridCheckwork gridCheckwork : gridCheckworkList) {
                        gridCheckwork.setGridId(grid.getGridId());
                        gridCheckwork.setUpdateUid(uid);
                        gridCheckwork.setUpdateTime(new Date());
                        checkWorkMapper.insert(gridCheckwork);
                    }
                }

            }
        }
        return grid;
    }

    //作业网格禁用判断
    @Override
    public Integer schedulingPlanCheck(GridTo gridTo) {
        Integer check = 0;
        //道路保洁排班查询
        QueryWrapper<EmpPlan> queryWrapperWorkPlan = new QueryWrapper<>();
        queryWrapperWorkPlan.lambda().eq(EmpPlan::getGridId, gridTo.getGridId());
        List<EmpPlan> workPlanList = empPlanMapper.selectList(queryWrapperWorkPlan);
        //机械清扫排班查询
        QueryWrapper<CarPlan> queryWrapperJxqsPlan = new QueryWrapper<>();
        queryWrapperJxqsPlan.lambda().eq(CarPlan::getGridId, gridTo.getGridId());
        List<CarPlan> CarPlanList = carPlanMapper.selectList(queryWrapperJxqsPlan);
        if (workPlanList.size() == 0 && CarPlanList.size() == 0) {
            check = 1;
        } else {
            check = 0;
        }
        return check;
    }

    @Override
    public void updateAndInsert(GridTo gridTo) {

//        QueryWrapper<GridBind> gridBindQueryWrapper = new QueryWrapper<>();
//        gridBindQueryWrapper.lambda().in(GridBind::getGridId, gridTo.getGridIdList());
//        List<GridBind> gridBindList = gridBindMapper.selectList(gridBindQueryWrapper);
//        Map<String, List<GridBind>> gridBindMap = gridBindList.stream().collect(Collectors.groupingBy(GridBind::getItemId));
//
//            if (null != gridTo.getItemIdList() && !gridTo.getItemIdList().isEmpty()) {
//                for (String itemId : gridTo.getItemIdList()) {
//                    List<GridBind> gridBindList1 = gridBindMap.get(itemId);
//                    if (null != gridBindList1) {
//                        for (GridBind gridBind : gridBindList1) {
//                            gridBind.setType(gridTo.getCarAndEmpType());
//                            gridBind.setItemId(itemId);
//                            gridBind.setGridId(gridTo.getGridIdList().get(0));
//                            gridBind.setGridName(gridTo.getName());
//                            gridBindMapper.updateById(gridBind);
//                        }
//                    } else {
//                        GridBind gridBind = new GridBind();
//                        gridBind.setType(gridTo.getCarAndEmpType());
//                        gridBind.setBindTime(StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
//                        gridBind.setItemId(itemId);
//                        gridBind.setGridId(gridTo.getGridIdList().get(0));
//                        gridBind.setGridName(gridTo.getName());
//                        gridBindMapper.insert(gridBind);
//                    }
//                }
//            }
        QueryWrapper<GridBind> gridBindQueryWrapper = new QueryWrapper<>();
        gridBindQueryWrapper.lambda().eq(GridBind::getItemId, gridTo.getItemId());
        List<GridBind> gridBindList = gridBindMapper.selectList(gridBindQueryWrapper);
        if (CollectionUtils.isNotEmpty(gridBindList) && gridBindList.size() > 0) {
            GridBind gridBind = gridBindList.get(0);
            gridBind.setGridId(gridTo.getGridId());
            gridBind.setBindTime(StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
            gridBindMapper.updateById(gridBind);
        } else {
            GridBind gridBind = new GridBind();
            gridBind.setType(gridTo.getCarAndEmpType());
            gridBind.setBindTime(StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
            gridBind.setItemId(gridTo.getItemId());
            gridBind.setGridId(gridTo.getGridId());
            gridBind.setGridName(gridTo.getName());
            //车辆人员信息查询
            if(gridTo.getCarAndEmpType().equals("car")){
                TlCar tlCar = tlCarService.getById(gridTo.getItemId());
                gridBind.setEmpldeptid(tlCar.getCardeptid());
                gridBind.setCarcategory(tlCar.getCarcategory());
                gridBind.setCarcategoryitem(tlCar.getCarcategoryitem());
                gridBind.setCartypeid(tlCar.getCartypeid());
            }else if(gridTo.getCarAndEmpType().equals("emp")){
                TlEmployee tlEmployee = tlEmployeeService.getById(gridTo.getItemId());
                gridBind.setEmpldeptid(tlEmployee.getEmpldeptid());
                gridBind.setPersontype(tlEmployee.getPersontype());
                gridBind.setWorktype(tlEmployee.getWorktype());
            }
            gridBindMapper.insert(gridBind);
        }

    }

    @Override
    public void updateAndInsert2(GridTo gridTo) {

        QueryWrapper<GridBind> gridBindQueryWrapper = new QueryWrapper<>();
        gridBindQueryWrapper.lambda().in(GridBind::getGridId, gridTo.getGridIdList());
        List<GridBind> gridBindList = gridBindMapper.selectList(gridBindQueryWrapper);
        Map<String, List<GridBind>> gridBindByGridMap = gridBindList.stream().collect(Collectors.groupingBy(GridBind::getGridId));

        if (null != gridTo.getGridIdList() && !gridTo.getGridIdList().isEmpty()) {
            for (String gridId : gridTo.getGridIdList()) {
                List<GridBind> gridBindList1 = gridBindByGridMap.get(gridId);
                if (null != gridBindList1) {
                    for (GridBind gridBind : gridBindList1) {
                        gridBind.setType(gridTo.getCarAndEmpType());
                        gridBind.setItemId(gridTo.getItemIdList().get(0));
                        gridBind.setGridId(gridId);
                        gridBind.setGridName(gridTo.getName());
                        gridBindMapper.updateById(gridBind);
                    }
                } else {
                    GridBind gridBind = new GridBind();
                    gridBind.setType(gridTo.getCarAndEmpType());
                    gridBind.setBindTime(StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
                    gridBind.setItemId(gridTo.getItemIdList().get(0));
                    gridBind.setGridId(gridId);
                    gridBind.setGridName(gridTo.getName());
                    //车辆人员信息查询
                    if(gridTo.getCarAndEmpType().equals("car")){
                        TlCar tlCar = tlCarService.getById(gridTo.getItemId());
                        gridBind.setEmpldeptid(tlCar.getCardeptid());
                        gridBind.setCarcategory(tlCar.getCarcategory());
                        gridBind.setCarcategoryitem(tlCar.getCarcategoryitem());
                        gridBind.setCartypeid(tlCar.getCartypeid());
                    }else if(gridTo.getCarAndEmpType().equals("emp")){
                        TlEmployee tlEmployee = tlEmployeeService.getById(gridTo.getItemId());
                        gridBind.setEmpldeptid(tlEmployee.getEmpldeptid());
                        gridBind.setPersontype(tlEmployee.getPersontype());
                        gridBind.setWorktype(tlEmployee.getWorktype());
                    }
                    gridBindMapper.insert(gridBind);
                }
            }
        }
//        QueryWrapper<GridBind> gridBindQueryWrapper = new QueryWrapper<>();
//        gridBindQueryWrapper.lambda().eq(GridBind::getItemId,gridTo.getItemId());
//        List<GridBind> gridBindList = gridBindMapper.selectList(gridBindQueryWrapper);
//        if(CollectionUtils.isNotEmpty(gridBindList) && gridBindList.size()>0){
//            GridBind gridBind = gridBindList.get(0);
//            gridBind.setGridId(gridTo.getGridId());
//            gridBind.setBindTime(StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
//            gridBindMapper.updateById(gridBind);
//        }else{
//            GridBind gridBind = new GridBind();
//            gridBind.setType(gridTo.getCarAndEmpType());
//            gridBind.setBindTime(StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
//            gridBind.setItemId(gridTo.getItemId());
//            gridBind.setGridId(gridTo.getGridId());
//            gridBind.setGridName(gridTo.getName());
//            gridBindMapper.insert(gridBind);
//        }
    }

    @Override
    public Integer checkGridList(GridTo gridTo) throws Exception {
//        List<Grid> gridList = gridMapper.selectList(new QueryWrapper<>());
//        Map<String, Grid> gridMap = gridList.stream().collect(Collectors.groupingBy(Grid::getGridId, Collectors.collectingAndThen(Collectors.toList(), grids -> grids.get(0))));
//        List<Map<String, Object>> originList = new ArrayList<>();
//        QueryWrapper<GridBind> gridBindQueryWrapper = new QueryWrapper<>();
//        gridBindQueryWrapper.lambda().in(GridBind::getItemId, gridTo.getItemIdList());
//        List<GridBind> gridBindList = gridBindMapper.selectList(gridBindQueryWrapper);
//
//        for (GridBind gridBind : gridBindList) {
//            Map<String, Object> map = new HashMap<>();
//            Grid grid = gridMap.get(gridBind.getGridId());
//            if (null != grid) {
//                map.put("start", grid.getStartTime());
//                map.put("end", grid.getEndTime());
//            }
//            originList.add(map);
//        }
//        List<String> stringList = new ArrayList<>();
//        if (null != gridTo.getGridIdList() && !gridTo.getGridIdList().isEmpty()) {
//            for (String gridId : gridTo.getGridIdList()) {
//                Grid grid = gridMapper.selectById(gridId);
//                boolean normal = isNormal(grid.getStartTime(), grid.getEndTime(), originList);
//                if (!normal) {
//                    stringList.add(grid.getName());
//                }
//            }
//        }
        QueryWrapper<GridBind> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(GridBind::getItemId, gridTo.getItemIdList());
        List<GridBind> gridBindList = gridBindMapper.selectList(queryWrapper);

        if (CollectionUtils.isNotEmpty(gridBindList) && gridBindList.size() > 0) {
            return 2;
        } else {
            return 1;
        }
    }

    @Override
    public List<Grid> gridIdList(List<String> gridsList) {
        List<Grid> GridList = new ArrayList<>();
        if (!gridsList.isEmpty()) {
            QueryWrapper<Grid> gridQueryWrapper = new QueryWrapper<>();
            gridQueryWrapper.lambda().in(Grid::getGridId, gridsList);
            GridList = gridMapper.selectList(gridQueryWrapper);
        }
        return GridList;
    }

    /**
     * 获取作业轨迹点集合
     *
     * @param gridList
     * @return
     */
    @Override
    public Map<String,List<GridPlace>> buildGridPlaceList(List<Grid> gridList) {
        Map<String,List<GridPlace>> gridPlaceListMap = new HashMap<>();
        SysDictType sysDictType = sysDictTypeService.getSysDictTypeByName("personnel_operation_completion_management_distance");
        if (Objects.nonNull(sysDictType)) {
            placeDistance = Double.valueOf(sysDictType.getDictValue());
        }
        for (Grid grid : gridList) {
            List<GridPlace> resultGridPlace = new ArrayList<>();
            System.out.println("grid.getGridId() =  " + grid.getGridId());
            Integer type = grid.getType();
            Integer areaType = grid.getAreaType();
            if ((type.equals(3) || type.equals(2)) && areaType.equals(6)) {//线
                List<GridPlace> gridPlaceList = JSONObject.parseArray(grid.getLnglat(), GridPlace.class);
                GridPlace gridPlace = gridPlaceList.get(0);
                List<GridPlace> addGridPlaceList = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(gridPlaceList)) {
                    addGridPlaceList = addGridPlaceList(gridPlace, gridPlaceList);
                }
                resultGridPlace = delGridPlaceList(addGridPlaceList);
            } else {//图形
                List<GridPlace> gridPlaceList = new ArrayList<>();
                if (type.equals(1) && areaType.equals(3)) {//圆
                    gridPlaceList = GridPlace.buildPointsCircular(Double.valueOf(grid.getLng()), Double.valueOf(grid.getLat()), grid.getRadius());
                } else if (type.equals(1) && areaType.equals(4)) {//矩形
                    gridPlaceList = GridPlace.buildPointsPolygon(buildRectangleGridPlaceList(grid.getLnglat()));
                } else {
                    gridPlaceList = GridPlace.buildPointsPolygon(JSONObject.parseArray(grid.getLnglat(), GridPlace.class));
                }
                List<GridPlace> line1 = new ArrayList<>();
                List<GridPlace> line2 = new ArrayList<>();
                line1.add(gridPlaceList.get(0));
                line1.add(gridPlaceList.get(3));
                line2.add(gridPlaceList.get(1));
                line2.add(gridPlaceList.get(2));
                if (CollectionUtils.isNotEmpty(line1)) {
                    line1 = addGridPlaceList(gridPlaceList.get(0), line1);
                }
                line1 = delGridPlaceList(line1);
                if (CollectionUtils.isNotEmpty(line2)) {
                    line2 = addGridPlaceList(gridPlaceList.get(1), line2);
                }
                line2 = delGridPlaceList(line2);
                line1 = removeOutGrid(grid, line1);
                line2 = removeOutGrid(grid, line2);
                resultGridPlace.addAll(line1);
                resultGridPlace.addAll(line2);
            }
            gridPlaceListMap.put(grid.getGridId(),resultGridPlace);
        }
        return gridPlaceListMap;
    }

    /**
     * 删除不在网格内的点
     *
     * @param grid
     * @param line1
     * @return
     */
    public List<GridPlace> removeOutGrid(Grid grid, List<GridPlace> line1) {
        List<GridPlace> gridPlaceList = new ArrayList<>();
        gridPlaceList.addAll(line1);
        for (int i = 0; i < gridPlaceList.size(); i++) {
            GridPlace x = gridPlaceList.get(i);
            if (grid.getType().equals(1) && grid.getAreaType().equals(3) && !DistanceUtils.insideCircle(Double.valueOf(x.getLng()), Double.valueOf(x.getLat()),
                    Double.valueOf(grid.getLng()), Double.valueOf(grid.getLat()), Double.valueOf(grid.getRadius()))) {
                gridPlaceList.remove(x);
            }
            if (grid.getType().equals(1) && grid.getAreaType().equals(4) && !DistanceUtils.insideRect(
                    Double.valueOf(x.getLng()), Double.valueOf(x.getLat()), grid.getLnglat())) {
                gridPlaceList.remove(x);
            }
            if (grid.getType().equals(1) && grid.getAreaType().equals(5) && !DistanceUtils.insidePolygon(
                    Double.valueOf(x.getLng()), Double.valueOf(x.getLat()), grid.getLnglat())) {
                gridPlaceList.remove(x);
            }
        }
        return gridPlaceList;
    }

    /**
     * 获取矩形两个点
     *
     * @param rectangle
     * @return
     */
    public List<GridPlace> buildRectangleGridPlaceList(String rectangle) {
        List<GridPlace> gridPlaceList = new ArrayList<>();
        gridPlaceList.add(JSONObject.parseObject(JSONObject.parseObject(rectangle).getString("Lq"), GridPlace.class));
        gridPlaceList.add(JSONObject.parseObject(JSONObject.parseObject(rectangle).getString("kq"), GridPlace.class));
        return gridPlaceList;
    }

    /**
     * 线段添点逻辑
     *
     * @param placeList 原始集合
     * @return
     */
    public List<GridPlace> addGridPlaceList(GridPlace gridPlace, List<GridPlace> placeList) {
        List<GridPlace> resultList = new ArrayList<>();
        placeList.forEach(x -> {
            x.setDistance(locationUtils.getDistance(Double.valueOf(x.getLat()), Double.valueOf(x.getLng()),
                    Double.valueOf(gridPlace.getLat()), Double.valueOf(gridPlace.getLng())));
        });
        resultList.addAll(placeList.stream().sorted(Comparator.comparing(GridPlace::getDistance).thenComparing(GridPlace::getLng).thenComparing(GridPlace::getLat)).collect(Collectors.toList()));

        for (int i = 1; i < placeList.size(); i++) {
            GridPlace thisPlace = placeList.get(i);
            GridPlace lastPlace = placeList.get(i - 1);
            Double distance = locationUtils.getDistance(Double.valueOf(thisPlace.getLat()), Double.valueOf(thisPlace.getLng()),
                    Double.valueOf(lastPlace.getLat()), Double.valueOf(lastPlace.getLng()));
            if (distance > (placeDistance * 2)) {
                resultList.add(GridPlace.buildGridPlace(Double.valueOf(thisPlace.getLng()), Double.valueOf(thisPlace.getLat())
                        , Double.valueOf(lastPlace.getLng()), Double.valueOf(lastPlace.getLat())));
            }
        }
        if (placeList.size() != resultList.size() && resultList.size() <= 1000) {
            return addGridPlaceList(gridPlace, resultList);
        } else {
            return resultList;
        }

    }

    /**
     * 删掉过密的点
     *
     * @param placeList
     * @return
     */
    public List<GridPlace> delGridPlaceList(List<GridPlace> placeList) {
        for (int i = 1; i < placeList.size(); i++) {
            GridPlace thisPlace = placeList.get(i);
            GridPlace lastPlace = placeList.get(i - 1);
            if (locationUtils.getDistance(Double.valueOf(thisPlace.getLat()), Double.valueOf(thisPlace.getLng()),
                    Double.valueOf(lastPlace.getLat()), Double.valueOf(lastPlace.getLng())) < placeDistance) {
                placeList.remove(thisPlace);
            }
        }
        return placeList;
    }

    /**
     * 不能循环调用
     */
    @Override
    public void initEmpWorkPointsList(Date date,List<Grid> gridList){
        Map<String, List<GridPlace>> gridPlaceListMap = buildGridPlaceList(gridList);
        List<EmpWorkPoints> empWorkPointsList = new ArrayList<>();
        for (String gridId : gridPlaceListMap.keySet()) {
            for (GridPlace gridPlace : gridPlaceListMap.get(gridId)) {
                empWorkPointsList.add(new EmpWorkPoints(IdUtils.simpleUUID().toString(),new BigDecimal(gridPlace.getLng())
                ,new BigDecimal(gridPlace.getLat()),gridId,date));
            }
        }
        empWorkPointsService.saveBatch(empWorkPointsList);
    }
}
